﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading;

namespace Com.PhilChuang.Utils.Mobile
{
	/// <summary>
	/// Summary description for MyExtensions
	/// </summary>
	public static partial class Extensions
	{
		#region Web
		public static void DoResponseStreamWork (this WebRequest req, int timeoutMs, Action<Stream> work)
		{
			// TODO TEST
			var finished = new ManualResetEvent (false);
			Exception ex = null;
			req.BeginGetResponse (
				ar =>
				{
					try
					{
						using (var res = req.EndGetResponse (ar))
						using (var resStream = res.GetResponseStream ())
						{
							work.Invoke (resStream);
						}
					}
					catch (Exception e)
					{
						ex = e;
					}
					finished.Set ();
				}, null);
			
			if (!finished.WaitOne (timeoutMs))
			{
				req.Abort ();
				throw new WebException ("Timeout during WebRequest.GetResponse ()", WebExceptionStatus.Timeout);
			}

			if (ex != null)
			{
				// do we lose information here?
				throw ex;
			}
		}
		#endregion

		#region ObservableCollection
		public static ObservableCollection<T> ToObservable<T> (this IEnumerable<T> items)
		{
			items.ThrowIfNull ("items");
			var oc = new ObservableCollection<T> ();
			foreach (var item in items)
				oc.Add (item);
			return oc;
		}

		public static void AddRange<T> (this ObservableCollection<T> self, IEnumerable<T> items)
		{
			self.ThrowIfNull ("self");
			if (items.IsNullOrEmpty ()) return;
			foreach (var item in items)
				self.Add (item);
		}
		#endregion

		#region Enum
		public static T[] EnumGetValues<T> ()
		{
			Type t = typeof (T);
			if (t.BaseType == typeof (Enum))
			{
				FieldInfo[] fi = t.GetFields (BindingFlags.Static | BindingFlags.Public);
				T[] vals = new T[fi.Length];
				for (int i = 0; i < fi.Length; i++)
					vals[i] = (T) fi[i].GetValue (null);
				return vals;
			}
			else
			{
				throw new ArgumentException (String.Format ("Given type {0} is not a System.Enum type", t.Name));
			}
		}

		public static bool EnumTryParse<T> (string s, out T result)
		{
			try
			{
				T e = (T) Enum.Parse (typeof (T), s, false);
				result = e;
				return true;
			}
			catch
			{
				result = default (T);
				return false;
			}
		}
		#endregion
	}
}